package com.spzx.channel.service.impl;

import com.alibaba.fastjson.JSON;
import com.esotericsoftware.minlog.Log;
import com.spzx.channel.domain.ItemVo;
import com.spzx.channel.service.IItemService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.*;
import io.reactivex.rxjava3.core.Completable;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.management.ThreadMXBean;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * ClassName: ItemServiceImpl
 * Package: com.spzx.channel.service.impl
 * Description:
 *
 * @Author ycy
 * @Create 2024/8/13 17:11
 * @Version 1.0
 */
@Slf4j
@Service
public class ItemServiceImpl implements IItemService {

    @Autowired
    private RemoteProductService remoteProductService;
    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @Override
    public ItemVo item(Long skuId) {

        // 远程调用商品微服务接口之前，提前知道用户访问商品SKUID是否存在于布隆过滤器
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter("sku:bloom:filter");

        if (!bloomFilter.contains(skuId)){
            // 查询数据不存在直接返回空对象
            log.error("用户查询商品sku不存在：{}" ,skuId);
            throw new ServiceException("用户查询商品sku不存在");
        }

        ItemVo itemVo = new ItemVo();

        //获取sku信息                                           // 后面的方法要调用 skuCompletableFuture，所以这里用supplyAsync()
        CompletableFuture<ProductSku> skuCompletableFuture = CompletableFuture.supplyAsync(() -> {
            R<ProductSku> productSkuR = remoteProductService.getProductSku(skuId,SecurityConstants.INNER);
            if(R.FAIL == productSkuR.getCode()){
                throw new ServiceException(productSkuR.getMsg());
            }
            ProductSku productSku = productSkuR.getData();
            itemVo.setProductSku(productSku);
            return productSku;
        },threadPoolExecutor);

        //获取商品信息
                                                                //调用前面 skuCompletableFuture ，所以使用 thenAcceptAsync()
        CompletableFuture<Void> productComCompletableFuture = skuCompletableFuture.thenAcceptAsync(productSku -> {
            R<Product> productR = remoteProductService.getProduct(productSku.getProductId(),SecurityConstants.INNER );
            if (R.FAIL == productR.getCode()){
                throw new ServiceException(productR.getMsg());
            }
            Product product = productR.getData();
            itemVo.setProduct(product);
            itemVo.setSliderUrlList(Arrays.asList(product.getSliderUrls().split(",")));
            itemVo.setSpecValueList(JSON.parseArray(product.getSpecValue()));
        },threadPoolExecutor);

        //获取商品最新价格
        CompletableFuture<Void> skuPriceCompletableFuture = CompletableFuture.runAsync(() -> {
            R<SkuPrice> skuPriceR = remoteProductService.getSkuPrice(skuId,SecurityConstants.INNER);
            if (R.FAIL == skuPriceR.getCode()){
                throw new ServiceException(skuPriceR.getMsg());
            }
            SkuPrice skuPrice = skuPriceR.getData();
            itemVo.setSkuPrice(skuPrice);
        },threadPoolExecutor);

        //获取商品详情
        CompletableFuture<Void> productDetailsComCompletableFuture = skuCompletableFuture.thenAcceptAsync(productSku -> {
            R<ProductDetails> productDetailsR = remoteProductService.getProductDetails(productSku.getProductId(),SecurityConstants.INNER);
            if (R.FAIL==productDetailsR.getCode()){
                throw new ServiceException(productDetailsR.getMsg());
            }
            ProductDetails productDetails = productDetailsR.getData();
            itemVo.setDetailsImageUrlList(Arrays.asList(productDetails.getImageUrls().split(",")));
        },threadPoolExecutor);


        //获取商品规格对应商品skuId信息
        CompletableFuture<Void> skuSpecValueComCompletableFuture = skuCompletableFuture.thenAcceptAsync(productSku -> {
            R<Map<String,Long>> skuSpecValueResult = remoteProductService.getSkuSpecValue(productSku.getProductId(),SecurityConstants.INNER);
            if (R.FAIL==skuSpecValueResult.getCode()){
                throw new SecurityException(skuSpecValueResult.getMsg());
            }
            Map<String,Long> skuSpecValueMap = skuSpecValueResult.getData();
            itemVo.setSkuSpecValueMap(skuSpecValueMap);
        }, threadPoolExecutor);



        // 获取商品库存信息

        CompletableFuture<Void> skuStockVoComCompletableFuture = CompletableFuture.runAsync(() -> {
            R<SkuStockVo> skuStockVoR = remoteProductService.getSkuStock(skuId,SecurityConstants.INNER);
            if (R.FAIL==skuStockVoR.getCode()){
                throw new ServiceException(skuStockVoR.getMsg());
            }
            SkuStockVo skuStockVo = skuStockVoR.getData();
            itemVo.setSkuStockVo(skuStockVo);
        },threadPoolExecutor);


        // 组合以上七个异步任务
        CompletableFuture.allOf(
                skuCompletableFuture,
                productComCompletableFuture,
                skuPriceCompletableFuture,
                productDetailsComCompletableFuture,
                skuSpecValueComCompletableFuture,
                skuStockVoComCompletableFuture
        ).join();

        return itemVo;
    }
}
